package org.turl.objects;

import org.turl.annotations.instanceConverter;
import org.turl.annotations.convertible;
import org.turl.wrappers.PolarToRectangularMapper;

/**
 * Created by tonyx
 * Date: Dec 30, 2007
 * Time: 9:53:36 AM
 */
public class PolarComplexNumber implements ComplexNumber,Navigable{
    protected double magnitude;
    protected Angle angle;

    protected double real;
    protected double img;

    @convertible(contractClass=ComplexNumber.class)
    @instanceConverter (instanceConverterMap = PolarToRectangularMapper.class)
    public PolarComplexNumber(double magnitude, Angle angle)
    {
        this.magnitude = magnitude;
        this.angle = angle;

        this.real = magnitude*Math.cos(angle.getValue());
        this.img =  magnitude*Math.sin(angle.getValue());
    }

    public double getReal() {
        return real;
    }

    public double getImg() {
        return magnitude*Math.sin(angle.getValue());
    }

    public double getMagnitude() {
        return magnitude;
    }

    public Angle getAngle() {
        return angle;
    }


    /**
     * tree traversal equals implementation. Subclasses with extrafields, should redefine _navigate and compareFields
     * in order to allow mixed type comparison
     * @param other
     * @return
     */
    public boolean equals(Object other) {
        if (other == null) return false;
        if (other == this) return true;
        if (!(other instanceof ComplexNumber)) return false;
        return _navigate(other, false);
    }

    public boolean _navigate(Object other, boolean reversed) {
        if (other instanceof ComplexNumber && !reversed) {
            return ((Navigable) other)._navigate(this, true);
        } else {
            return _compareFields(other);
        }

    }

    private boolean _compareFields(Object other) {
        if (other instanceof ComplexNumber) {
            ComplexNumber rOther = (ComplexNumber) other;
            return !(this.real != rOther.getReal() || this.img != rOther.getImg());
        } else
            return false;
    }


    public int hashCode()
    {
        return ((int)(img+real))%37;
    }
    public String toString()
    {
        return "actual type: "+this.getClass().toString()+"real: "+this.getReal()+"; img: "+this.getImg()+
                "; magnitude: "+this.getMagnitude()+"; angle: "+this.getAngle().getValue();
    }

}
